from generate_common import handleValueApply

def genDx(ruleDatum, ruleAct, filterDatum, hsp_abbr):

    # 获得operator，值要么就是 with，要么就是 without
    operator = filterDatum['operator']
    # 针对 operator，如果是 without，则 NOT
    operKeepSql = "" if operator == 'with' else "NOT"
    operDropSql = "NOT" if operator == 'with' else ""

    # 获得要判断存在或者不存在的值列表，并且转换为 sql 语句
    valueRaw = filterDatum['value']
    valueRawSql = ''
    valueRawSql = ''
    valueRawSql = ''
    valueRawSql = ''
    valueRawSql = ''
    for value in valueRaw:
        valueRawSql += f" OR m.in_dx_name like '{value}'"
        valueRawSql += f" OR m.out_dx_code like '{value}'"
        valueRawSql += f" OR m.out_dx_name like '{value}'"
        valueRawSql += f" OR m.dise_no like '{value}'"
        valueRawSql += f" OR m.dise_name like '{value}'"

    # 获得value_apply，值是一个列表，里面的code是编码；另外value是name的列表
    valueCodesSql, valueNamesSql = handleValueApply(filterDatum)
    # 将 dx_code 换成 dx_j_code
    if valueCodesSql:
        valueCodesSql = valueCodesSql.replace("dx_code", "dx_j_code")

    # 获得 inOne，默认值为 "case"
    inOne = filterDatum.get('in_one_', 'case')
    
    # 构建SQL语句，除非 valueCodes 和 valueNames 都为空，则不需要查询 dx 表
    if not valueCodesSql and not valueNamesSql:
        return []  # 如果没有诊断条件，直接返回原始SQL

    # ============ 思路 ============
    """
    如果是 without：则诊断没有关键字才作为违规信息保留
    1. 删除诊断条件不符合的部分，删除 dx 表中有对应诊断的部分
    2. 进一步删除诊断条件不符合的部分，删除 m 表中有对应诊断的部分，按顺序删除 in_dx_name、out_dx_code、out_dx_name、dise_no、dise_name 五个字段
    
    如果是 with：则诊断有关键字才作为违规信息保留
    1. 对 dx 表中有对应诊断的部分做标记，将 va 表的 str1 标记为 '1'
    2. 进一步对 m 表中有对应诊断的部分做标记，按顺序标记 in_dx_name、out_dx_code、out_dx_name、dise_no、dise_name 五个字段，任意一个字段符合条件则标记为 '1'
    3. 删除标记不为 '1' 的部分    
    """
    # ============ 思路 END ============

    # 根据不同的 inOne 条件，生成不同的连接键
    if inOne == 'case':
        joinKey = "va.setl_id = dx.setl_id"
    elif inOne == 'year':
        joinKey = "va.psn_no = dx.psn_no and va.j_year = dx.j_year"
    elif inOne == 'patient':
        joinKey = "va.psn_no = dx.psn_no"

    if operator == 'with' and valueCodesSql:
        sqlList = [
            # 第1步，对 dx 表中符合的部分做标记
            f"""
                -- dx with，step1，标记 dx 表中符合的部分
                UPDATE vlt_tmp_a va
                SET str1 = '1'
                WHERE EXISTS (
                    SELECT 1 FROM dx
                    WHERE 1=1 AND {joinKey}
                    {valueCodesSql} {valueNamesSql}
                )
            """,
            # 第2步，进一步对 m 表中符合的部分做标记
            f"""
                -- dx，step2，标记 m 表中符合的部分
                UPDATE vlt_tmp_a va
                SET str1 = '1'
                WHERE str1 IS NULL
                    AND EXISTS (
                        SELECT 1 FROM m
                        WHERE va.setl_id = m.setl_id
                            AND (
                                1=0 {valueRawSql}
                            )
                    )
            """,
            # 第3步，删除标记不为 '1' 的部分
            f"""
                -- dx，step3，删除标记不为 '1' 的部分
                DELETE FROM vlt_tmp_a va
                WHERE str1 IS NULL
            """,
        ]
    elif operator == 'without' and valueCodesSql:
        sqlList = [
            # 第1步，删掉 dx 表中不符合的部分
            f"""
                -- dx without，step1，删掉 dx 表中不符合的部分
                DELETE FROM vlt_tmp_a va
                WHERE {operDropSql} EXISTS (
                    SELECT 1 FROM dx
                    WHERE 1=1 AND {joinKey}
                    {valueCodesSql} {valueNamesSql}
                )
            """,
            # 第2步，进一步删掉 m 表中不符合的部分
            f"""
                -- dx，step2，删掉 m 表中不符合的部分
                DELETE FROM vlt_tmp_a va
                WHERE {operDropSql} EXISTS (
                    SELECT 1 FROM m
                    WHERE va.setl_id = m.setl_id
                        AND (
                            1=0 {valueRawSql}
                        )
                )
            """,
        ]
    elif operator == 'with' and not valueCodesSql:
        # 带有某个诊断的才违规，但是没有符合的诊断，所以不可能有违规，直接返回空的记录
        sqlList = [
            """
                -- dx with but no matching codes，没有符合的 with 条件，直接删除所有记录
                DELETE FROM vlt_tmp_a
            """
        ]
    elif operator == 'without' and not valueCodesSql:
        # 不带有某个诊断的才违规，但是没有符合的诊断，所以所有记录都违规，直接返回原始SQL
        sqlList = [
            """
                -- dx without but no matching codes，没有符合的 without 条件，保留所有记录
                -- No operation needed
                DELETE FROM vlt_tmp_a WHERE 1=0
            """
        ]

    return sqlList
